/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package com.dejax.service.impl;

import com.dejax.domain.DevopsOperation;
import com.dejax.exception.BadRequestException;
import com.dejax.utils.ValidationUtil;
import com.dejax.utils.FileUtil;
import lombok.RequiredArgsConstructor;
import com.dejax.repository.DevopsOperationRepository;
import com.dejax.service.DevopsOperationService;
import com.dejax.service.dto.DevopsOperationDto;
import com.dejax.service.dto.DevopsOperationQueryCriteria;
import com.dejax.service.mapstruct.DevopsOperationMapper;
import org.hibernate.query.NativeQuery;
import org.hibernate.transform.Transformers;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.hutool.core.util.IdUtil;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import com.dejax.utils.PageUtil;
import com.dejax.utils.QueryHelp;

import java.math.BigDecimal;
import java.util.*;
import java.io.IOException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.servlet.http.HttpServletResponse;

import static org.springframework.http.HttpStatus.BAD_REQUEST;

/**
* @website https://el-admin.vip
* @description 服务实现
* @author Richer
* @date 2022-01-06
**/
@Service
@RequiredArgsConstructor
public class DevopsOperationServiceImpl implements DevopsOperationService {

    private final DevopsOperationRepository devopsOperationRepository;
    private final DevopsOperationMapper devopsOperationMapper;

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public Map<String,Object> queryAll(DevopsOperationQueryCriteria criteria, Pageable pageable){
        criteria.setFlag(0);
        Page<DevopsOperation> page = this.queryAllData(criteria,pageable);

        return PageUtil.toPage(page);
        //return PageUtil.toPage(page.map(devopsOperationMapper::toDto));
    }

    private Page<DevopsOperation> queryAllData(DevopsOperationQueryCriteria criteria, Pageable pageable){
        StringBuffer dataBuffer = new StringBuffer(
                "SELECT devops_operation.*,jenkinsclient.ip " +
                        "FROM devops_operation " +
                        "left join devops_jenkinsclient jenkinsclient on  jenkinsclient.jenkinsid =devops_operation.jenkinsid " +
                        "WHERE 1 = 1 ");
        StringBuffer countBuffer = new StringBuffer(
                "SELECT count(*) " +
                        "FROM devops_operation " +
                        "left join devops_jenkinsclient jenkinsclient on  jenkinsclient.jenkinsid =devops_operation.jenkinsid " +
                        "WHERE 1 = 1 ");

        StringBuffer paramBuffer = new StringBuffer();

        //功能名称
        if(criteria.getJenkinsid() != null){
            paramBuffer.append(" AND (jenkinsclient.ip = '" + criteria.getJenkinsid() + "' or  jenkinsclient.jenkinsid = '"+criteria.getJenkinsid()+"' )");
        }

        paramBuffer.append(" AND devops_operation.flag = 0");
        StringBuffer orderBuffer = new StringBuffer(
                "");

        String dataSql = (dataBuffer.append(paramBuffer).append(orderBuffer))
                .toString();
        String countSql = (countBuffer.append(paramBuffer)).toString();

        System.out.println("{} dataSql= " + dataSql);
        System.out.println("{} countSql= " + countSql);

        Query dataQuery = entityManager.createNativeQuery(dataSql.toString());
        Query countQuery = entityManager.createNativeQuery(countSql.toString());

        dataQuery.setFirstResult((int) pageable.getOffset());
        dataQuery.setMaxResults(pageable.getPageSize());
        dataQuery.unwrap(NativeQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        BigDecimal count = BigDecimal.valueOf(Integer.valueOf(String.valueOf(countQuery.getSingleResult())));
        Integer total = count.intValue();

        List content = total > pageable.getOffset() ? dataQuery
                .getResultList() : Collections.emptyList();
        return new PageImpl<DevopsOperation>(content,pageable,total);
    }

    @Override
    public List<DevopsOperationDto> queryAll(DevopsOperationQueryCriteria criteria){
        criteria.setFlag(0);
        return devopsOperationMapper.toDto(devopsOperationRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public DevopsOperationDto findById(String operationid) {
        DevopsOperation devopsOperation = devopsOperationRepository.findById(operationid).orElseGet(DevopsOperation::new);
        ValidationUtil.isNull(devopsOperation.getOperationid(),"DevopsOperation","operationid",operationid);
        return devopsOperationMapper.toDto(devopsOperation);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public DevopsOperationDto create(DevopsOperation resources) {
        //先查重复
        if(devopsOperationRepository.findOne(resources.getJobNamespace(),resources.getJenkinsid(),resources.getOperateType()).size()>0 ){
            throw new BadRequestException(BAD_REQUEST, "已存在");
        }
        resources.setOperationid(IdUtil.simpleUUID());
        resources.setFlag(0);
        return devopsOperationMapper.toDto(devopsOperationRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(DevopsOperation resources) {
        DevopsOperation devopsOperation = devopsOperationRepository.findById(resources.getOperationid()).orElseGet(DevopsOperation::new);
        ValidationUtil.isNull( devopsOperation.getOperationid(),"DevopsOperation","id",resources.getOperationid());
        devopsOperation.copy(resources);
        //查重
        List<DevopsOperation> list = devopsOperationRepository.findOne(resources.getJobNamespace(),resources.getJenkinsid(),resources.getOperateType());

        if(list.size() > 1 || (list.size() > 0 && !list.get(0).getOperationid().equals(resources.getOperationid()))){
            throw new BadRequestException(BAD_REQUEST, "已存在");
        }
        devopsOperationRepository.save(devopsOperation);
    }

    @Override
    public void deleteAll(String[] ids) {
        DevopsOperation updatesource = new DevopsOperation();
        for (String operationid : ids) {
            updatesource.setFlag(1);
            updatesource.setOperationid(operationid);
            this.update(updatesource);
        }
    }

    @Override
    public void download(List<DevopsOperationDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (DevopsOperationDto devopsOperation : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("操作描述", devopsOperation.getJobDesc());
            map.put("操作命名", devopsOperation.getJobNamespace());
            map.put("ip", devopsOperation.getJenkinsid());
            map.put("操作类型", devopsOperation.getOperateType());
            map.put("参数类型", devopsOperation.getOperateparamsType());
            map.put("操作参数", devopsOperation.getOperateparams());
            map.put(" flag",  devopsOperation.getFlag());
            map.put(" notes",  devopsOperation.getNotes());
            map.put(" reguser",  devopsOperation.getReguser());
            map.put(" regtime",  devopsOperation.getRegtime());
            map.put(" moduser",  devopsOperation.getModuser());
            map.put(" modtime",  devopsOperation.getModtime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}